package com.example.thread;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 上面两个程序 都只有两个线程, 可以用cdl做一些通信即可
 * @param <T>
 */
public class MyContainer2Lock<T> {

    private LinkedList<T> linkedList = new LinkedList();
    private int max =10;
    private Lock lock = new ReentrantLock();
    Condition producer = lock.newCondition();
    Condition consumer = lock.newCondition();
    private void put(T t) throws Exception{
        lock.lock();
        while (linkedList.size()==max){
            System.out.println("仓库已满 暂停生产");
            producer.await();
        }
        linkedList.add(t);
        System.out.println("生产");
        consumer.signalAll();
        lock.unlock();
    }

    private T get() throws Exception {
        lock.lock();
        while (linkedList.size()==0){//TODO 如果是if 可能唤醒两个消费者线程
            System.out.println("仓库为空 暂停消费");
            consumer.await();
        }
        T t =linkedList.removeFirst();
        System.out.println("消费");
        producer.signalAll();
        lock.unlock();
        return t;
    }

    public static void main(String[] args) {
        MyContainer2Lock myContainer2Lock = new MyContainer2Lock();
        for(int i=0;i<10;i++){
            new Thread(()->{
                try {
                    myContainer2Lock.get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
        for(int i=0;i<2;i++){
            int finalI = i;
            new Thread(()->{
                try {
                    myContainer2Lock.put(finalI);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

}
